<template>
  <div 
    class="starfield-wrapper" 
    :class="{ interactive: interactive }"
    ref="starfieldRef"
  >
    <canvas ref="canvasRef" class="starfield-canvas"></canvas>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'

// Props定义
const props = defineProps({
  // 星星数量
  starCount: {
    type: Number,
    default: 60
  },
  // 连线最大距离
  connectionDistance: {
    type: Number,
    default: 120
  },
  // 是否启用鼠标交互
  interactive: {
    type: Boolean,
    default: true
  },
  // 鼠标影响范围
  mouseRadius: {
    type: Number,
    default: 100
  },
  // 鼠标推力强度
  mousePower: {
    type: Number,
    default: 5
  },
  // 流星数量
  meteorCount: {
    type: Number,
    default: 0
  },
  // 是否显示鼠标影响范围
  showMouseArea: {
    type: Boolean,
    default: false
  }
})

// Refs
const starfieldRef = ref(null)
const canvasRef = ref(null)
let ctx = null
let animationId = null
let stars = []
let meteors = []
let mouse = {
  x: -1000,
  y: -1000,
  radius: props.mouseRadius
}

// 星星类
class Star {
  constructor(canvas) {
    this.canvas = canvas
    this.x = Math.random() * canvas.width
    this.y = Math.random() * canvas.height
    
    // 随机速度和方向
    const angle = Math.random() * Math.PI * 2
    const speed = Math.random() * 0.5 + 0.1
    this.vx = Math.cos(angle) * speed
    this.vy = Math.sin(angle) * speed
    
    // 星星属性
    this.radius = Math.random() * 2 + 1.5
    this.opacity = Math.random() * 0.6 + 0.4
    
    // 闪烁属性
    this.twinkleSpeed = Math.random() * 0.02 + 0.01
    this.twinklePhase = Math.random() * Math.PI * 2
  }
  
  update() {
    // 鼠标排斥效果
    if (props.interactive) {
      const distX = this.x - mouse.x
      const distY = this.y - mouse.y
      const distance = Math.sqrt(distX * distX + distY * distY)
      
      if (distance < mouse.radius && distance > 0) {
        const force = (mouse.radius - distance) / mouse.radius
        const angle = Math.atan2(distY, distX)
        
        // 直接改变速度，使效果更明显
        this.vx += Math.cos(angle) * force * props.mousePower * 0.5
        this.vy += Math.sin(angle) * force * props.mousePower * 0.5
        
        // 限制最大速度
        const maxSpeed = 5
        const speed = Math.sqrt(this.vx * this.vx + this.vy * this.vy)
        if (speed > maxSpeed) {
          this.vx = (this.vx / speed) * maxSpeed
          this.vy = (this.vy / speed) * maxSpeed
        }
      }
    }
    
    // 速度衰减（让星星逐渐恢复正常速度）
    this.vx *= 0.98
    this.vy *= 0.98
    
    // 保持最小速度
    const minSpeed = 0.1
    const currentSpeed = Math.sqrt(this.vx * this.vx + this.vy * this.vy)
    if (currentSpeed < minSpeed) {
      const angle = Math.atan2(this.vy, this.vx)
      this.vx = Math.cos(angle) * minSpeed
      this.vy = Math.sin(angle) * minSpeed
    }
    
    // 更新位置
    this.x += this.vx
    this.y += this.vy
    
    // 边界处理 - 从另一边出现
    if (this.x < -10) this.x = this.canvas.width + 10
    if (this.x > this.canvas.width + 10) this.x = -10
    if (this.y < -10) this.y = this.canvas.height + 10
    if (this.y > this.canvas.height + 10) this.y = -10
    
    // 更新闪烁
    this.twinklePhase += this.twinkleSpeed
  }
  
  draw(ctx) {
    const twinkle = Math.sin(this.twinklePhase) * 0.3 + 0.7
    
    ctx.save()
    ctx.globalAlpha = this.opacity * twinkle
    
    // 绘制星星光晕
    const gradient = ctx.createRadialGradient(
      this.x, this.y, 0,
      this.x, this.y, this.radius * 4
    )
    gradient.addColorStop(0, 'rgba(255, 255, 255, 0.8)')
    gradient.addColorStop(0.1, 'rgba(255, 255, 255, 0.5)')
    gradient.addColorStop(0.5, 'rgba(147, 197, 253, 0.2)')
    gradient.addColorStop(1, 'rgba(147, 197, 253, 0)')
    
    ctx.fillStyle = gradient
    ctx.beginPath()
    ctx.arc(this.x, this.y, this.radius * 4, 0, Math.PI * 2)
    ctx.fill()
    
    // 绘制星星核心
    ctx.globalAlpha = this.opacity
    ctx.fillStyle = '#ffffff'
    ctx.beginPath()
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2)
    ctx.fill()
    
    ctx.restore()
  }
}

// 计算点到线段的距离
const pointToLineDistance = (px, py, x1, y1, x2, y2) => {
  const A = px - x1
  const B = py - y1
  const C = x2 - x1
  const D = y2 - y1
  
  const dot = A * C + B * D
  const lenSq = C * C + D * D
  let param = -1
  
  if (lenSq !== 0) {
    param = dot / lenSq
  }
  
  let xx, yy
  
  if (param < 0) {
    xx = x1
    yy = y1
  } else if (param > 1) {
    xx = x2
    yy = y2
  } else {
    xx = x1 + param * C
    yy = y1 + param * D
  }
  
  const dx = px - xx
  const dy = py - yy
  
  return Math.sqrt(dx * dx + dy * dy)
}

// 绘制连线
const drawConnections = () => {
  ctx.save()
  
  for (let i = 0; i < stars.length; i++) {
    for (let j = i + 1; j < stars.length; j++) {
      const dx = stars[i].x - stars[j].x
      const dy = stars[i].y - stars[j].y
      const distance = Math.sqrt(dx * dx + dy * dy)
      
      if (distance < props.connectionDistance) {
        // 检查鼠标到连线的距离
        const mouseToLineDistance = pointToLineDistance(
          mouse.x, mouse.y,
          stars[i].x, stars[i].y,
          stars[j].x, stars[j].y
        )
        
        let opacity = (1 - distance / props.connectionDistance) * 0.4
        
        // 如果鼠标靠近连线，降低透明度或完全隐藏
        if (mouseToLineDistance < mouse.radius) {
          opacity *= Math.max(0, (mouseToLineDistance / mouse.radius) * 0.5)
          
          // 推开两端的星星
          if (props.interactive && mouseToLineDistance < mouse.radius * 0.7) {
            const midX = (stars[i].x + stars[j].x) / 2
            const midY = (stars[i].y + stars[j].y) / 2
            
            // 推开第一个星星
            const dist1X = stars[i].x - midX
            const dist1Y = stars[i].y - midY
            const angle1 = Math.atan2(dist1Y, dist1X)
            const pushForce = (1 - mouseToLineDistance / (mouse.radius * 0.7)) * 2
            
            stars[i].vx += Math.cos(angle1) * pushForce
            stars[i].vy += Math.sin(angle1) * pushForce
            
            // 推开第二个星星
            const dist2X = stars[j].x - midX
            const dist2Y = stars[j].y - midY
            const angle2 = Math.atan2(dist2Y, dist2X)
            
            stars[j].vx += Math.cos(angle2) * pushForce
            stars[j].vy += Math.sin(angle2) * pushForce
          }
        }
        
        if (opacity > 0.01) {
          ctx.globalAlpha = opacity * stars[i].opacity * stars[j].opacity
          ctx.strokeStyle = '#93c5fd'
          ctx.lineWidth = 1
          ctx.beginPath()
          ctx.moveTo(stars[i].x, stars[i].y)
          ctx.lineTo(stars[j].x, stars[j].y)
          ctx.stroke()
        }
      }
    }
  }
  
  ctx.restore()
}

// 流星类
class Meteor {
  constructor(canvas) {
    this.canvas = canvas
    this.reset()
  }
  
  reset() {
    this.x = Math.random() * this.canvas.width * 1.5 - this.canvas.width * 0.25
    this.y = -50
    this.length = Math.random() * 80 + 50
    this.speed = Math.random() * 8 + 5
    this.opacity = 0
    this.fadeIn = true
    this.angle = Math.PI / 4 + (Math.random() - 0.5) * 0.3
  }
  
  update() {
    this.x += Math.cos(this.angle) * this.speed
    this.y += Math.sin(this.angle) * this.speed
    
    if (this.fadeIn) {
      this.opacity += 0.02
      if (this.opacity >= 0.8) {
        this.fadeIn = false
      }
    } else if (this.y > this.canvas.height * 0.5) {
      this.opacity -= 0.01
    }
    
    if (this.y > this.canvas.height || this.opacity <= 0) {
      this.reset()
    }
  }
  
  draw(ctx) {
    ctx.save()
    ctx.globalAlpha = this.opacity
    
    // 绘制流星轨迹
    const gradient = ctx.createLinearGradient(
      this.x - Math.cos(this.angle) * this.length,
      this.y - Math.sin(this.angle) * this.length,
      this.x,
      this.y
    )
    gradient.addColorStop(0, 'rgba(255, 255, 255, 0)')
    gradient.addColorStop(0.7, 'rgba(255, 255, 255, 0.4)')
    gradient.addColorStop(1, 'rgba(255, 255, 255, 0.8)')
    
    ctx.strokeStyle = gradient
    ctx.lineWidth = 1.5
    ctx.beginPath()
    ctx.moveTo(
      this.x - Math.cos(this.angle) * this.length,
      this.y - Math.sin(this.angle) * this.length
    )
    ctx.lineTo(this.x, this.y)
    ctx.stroke()
    
    // 绘制流星头部
    const headGradient = ctx.createRadialGradient(
      this.x, this.y, 0,
      this.x, this.y, 8
    )
    headGradient.addColorStop(0, 'rgba(255, 255, 255, 1)')
    headGradient.addColorStop(0.5, 'rgba(147, 197, 253, 0.5)')
    headGradient.addColorStop(1, 'rgba(147, 197, 253, 0)')
    
    ctx.fillStyle = headGradient
    ctx.beginPath()
    ctx.arc(this.x, this.y, 8, 0, Math.PI * 2)
    ctx.fill()
    
    ctx.restore()
  }
}

// 初始化画布
const initCanvas = () => {
  const canvas = canvasRef.value
  const wrapper = starfieldRef.value
  
  canvas.width = wrapper.offsetWidth
  canvas.height = wrapper.offsetHeight
  
  ctx = canvas.getContext('2d')
  
  // 创建星星
  stars = []
  for (let i = 0; i < props.starCount; i++) {
    stars.push(new Star(canvas))
  }
  
  // 创建流星
  meteors = []
  for (let i = 0; i < props.meteorCount; i++) {
    meteors.push(new Meteor(canvas))
  }
  
  // 绘制鼠标影响范围（可选的视觉反馈）
  const drawMouseArea = () => {
    if (props.interactive && props.showMouseArea && mouse.x > 0 && mouse.y > 0) {
      ctx.save()
      
      // 绘制外圈
      ctx.globalAlpha = 0.05
      ctx.strokeStyle = '#60a5fa'
      ctx.lineWidth = 1
      ctx.beginPath()
      ctx.arc(mouse.x, mouse.y, mouse.radius, 0, Math.PI * 2)
      ctx.stroke()
      
      // 绘制内圈渐变
      const gradient = ctx.createRadialGradient(
        mouse.x, mouse.y, 0,
        mouse.x, mouse.y, mouse.radius
      )
      gradient.addColorStop(0, 'rgba(96, 165, 250, 0.1)')
      gradient.addColorStop(1, 'rgba(96, 165, 250, 0)')
      
      ctx.fillStyle = gradient
      ctx.beginPath()
      ctx.arc(mouse.x, mouse.y, mouse.radius, 0, Math.PI * 2)
      ctx.fill()
      
      ctx.restore()
    }
  }

  // 动画循环
  const animate = () => {
    // 清除画布
    ctx.fillStyle = '#0a0e1a'
    ctx.fillRect(0, 0, canvas.width, canvas.height)
    
    // 绘制鼠标影响范围（可选）
    drawMouseArea()
    
    // 绘制连线
    drawConnections()
    
    // 更新和绘制星星
    stars.forEach(star => {
      star.update()
      star.draw(ctx)
    })
    
    // 更新和绘制流星
    meteors.forEach(meteor => {
      meteor.update()
      meteor.draw(ctx)
    })
    
    animationId = requestAnimationFrame(animate)
  }
  
  animate()
}

// 处理窗口大小变化
const handleResize = () => {
  if (canvasRef.value && starfieldRef.value) {
    const canvas = canvasRef.value
    const wrapper = starfieldRef.value
    
    canvas.width = wrapper.offsetWidth
    canvas.height = wrapper.offsetHeight
    
    // 调整星星位置
    stars.forEach(star => {
      star.canvas = canvas
      if (star.x > canvas.width) star.x = canvas.width
      if (star.y > canvas.height) star.y = canvas.height
    })
  }
}

// 处理鼠标移动
const handleMouseMove = (e) => {
  if (!props.interactive) return
  const rect = canvasRef.value.getBoundingClientRect()
  mouse.x = e.clientX - rect.left
  mouse.y = e.clientY - rect.top
}

// 处理鼠标离开
const handleMouseLeave = () => {
  mouse.x = -1000
  mouse.y = -1000
}

onMounted(() => {
  initCanvas()
  window.addEventListener('resize', handleResize)
  if (props.interactive && starfieldRef.value) {
    starfieldRef.value.addEventListener('mousemove', handleMouseMove)
    starfieldRef.value.addEventListener('mouseleave', handleMouseLeave)
  }
})

onBeforeUnmount(() => {
  if (animationId) {
    cancelAnimationFrame(animationId)
  }
  window.removeEventListener('resize', handleResize)
  if (props.interactive && starfieldRef.value) {
    starfieldRef.value.removeEventListener('mousemove', handleMouseMove)
    starfieldRef.value.removeEventListener('mouseleave', handleMouseLeave)
  }
})
</script>

<style lang="scss" scoped>
.starfield-wrapper {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  z-index: 0;
  
  &.interactive {
    pointer-events: auto;
  }
  
  &:not(.interactive) {
    pointer-events: none;
  }
}

.starfield-canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: transparent;
}
</style>